home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / dev / cross / avra-0.4_src.lha / avra-0.4 / directiv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-24  |  18.4 KB  |  769 lines

  1. /***********************************************************************
  2.  *  avra - Assembler for the Atmel AVR microcontroller series
  3.  *  Copyright (C) 1998-1999 Jon Anders Haugum
  4.  *
  5.  *  This program is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2 of the License, or
  8.  *  (at your option) any later version.
  9.  *
  10.  *  This program is distributed in the hope that it will be useful,
  11.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  *  GNU General Public License for more details.
  14.  *
  15.  *  You should have received a copy of the GNU General Public License
  16.  *  along with this program; see the file COPYING.  If not, write to
  17.  *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  18.  *  Boston, MA 02111-1307, USA.
  19.  *
  20.  *
  21.  *  Author of avra can be reached at:
  22.  *     email: jonah@omegav.ntnu.no
  23.  *     www: http://www.omegav.ntnu.no/~jonah/el/avra.html
  24.  */
  25.  
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <ctype.h>
  30.  
  31. #include "misc.h"
  32. #include "args.h"
  33. #include "avra.h"
  34. #include "device.h"
  35.  
  36. enum
  37.     {
  38.     DIRECTIVE_BYTE = 0,
  39.     DIRECTIVE_CSEG,
  40.     DIRECTIVE_DB,
  41.     DIRECTIVE_DEF,
  42.     DIRECTIVE_DEVICE,
  43.     DIRECTIVE_DSEG,
  44.     DIRECTIVE_DW,
  45.     DIRECTIVE_ENDM,
  46.     DIRECTIVE_ENDMACRO,
  47.     DIRECTIVE_EQU,
  48.     DIRECTIVE_ESEG,
  49.     DIRECTIVE_EXIT,
  50.     DIRECTIVE_INCLUDE,
  51.     DIRECTIVE_LIST,
  52.     DIRECTIVE_LISTMAC,
  53.     DIRECTIVE_MACRO,
  54.     DIRECTIVE_NOLIST,
  55.     DIRECTIVE_ORG,
  56.     DIRECTIVE_SET,
  57.     DIRECTIVE_DEFINE,
  58.     DIRECTIVE_UNDEF,
  59.     DIRECTIVE_IFDEF,
  60.     DIRECTIVE_IFNDEF,
  61.     DIRECTIVE_IF,
  62.     DIRECTIVE_ELSE,
  63.     DIRECTIVE_ELIF,
  64.     DIRECTIVE_ENDIF,
  65.     DIRECTIVE_MESSAGE,
  66.     DIRECTIVE_WARNING,
  67.     DIRECTIVE_ERROR,
  68.     DIRECTIVE_COUNT
  69.     };
  70.  
  71. char *directive_list[] =
  72.     {
  73.     "BYTE",
  74.     "CSEG",
  75.     "DB",
  76.     "DEF",
  77.     "DEVICE",
  78.     "DSEG",
  79.     "DW",
  80.     "ENDM",
  81.     "ENDMACRO",
  82.     "EQU",
  83.     "ESEG",
  84.     "EXIT",
  85.     "INCLUDE",
  86.     "LIST",
  87.     "LISTMAC",
  88.     "MACRO",
  89.     "NOLIST",
  90.     "ORG",
  91.     "SET",
  92.     "DEFINE",
  93.     "UNDEF",
  94.     "IFDEF",
  95.     "IFNDEF",
  96.     "IF",
  97.     "ELSE",
  98.     "ELIF",
  99.     "ENDIF",
  100.     "MESSAGE",
  101.     "WARNING",
  102.     "ERROR"
  103.     };
  104.  
  105.  
  106. int parse_directive(struct prog_info *pi, int pass)
  107.     {
  108.     int directive, ok = True, i;
  109.     char *next, *data;
  110.     struct file_info *fi_bak;
  111.     struct label *label;
  112.     struct def *def;
  113.  
  114.     next = get_next_token(pi->fi->scratch, TERM_SPACE);
  115.     for(i = 0; pi->fi->scratch[i] != '\0'; i++)
  116.         pi->fi->scratch[i] = toupper(pi->fi->scratch[i]);
  117.     directive = get_directive_type(pi->fi->scratch + 1);
  118.     if(directive == -1)
  119.         {
  120.         print_msg(pi, MSGTYPE_ERROR, "Unknown directive: %s", pi->fi->scratch);
  121.         return(True);
  122.         }
  123.     switch(directive)
  124.         {
  125.         case DIRECTIVE_BYTE:
  126.             if(!next)
  127.                 {
  128.                 print_msg(pi, MSGTYPE_ERROR, ".BYTE needs an operand");
  129.                 return(True);
  130.                 }
  131.             if(pi->segment != SEGMENT_DATA)
  132.                 print_msg(pi, MSGTYPE_ERROR, ".BYTE directive can only be used in data segment (.DSEG)");
  133.             get_next_token(next, TERM_END);
  134.             if(!get_expr(pi, next, &i))
  135.                 return(False);
  136.             if((pass == PASS_2) && pi->list_line && pi->list_on)
  137.                 {
  138.                 fprintf(pi->list_file, "%06x      %s", pi->dseg_addr, pi->list_line);
  139.                 pi->list_line = NULL;
  140.                 }
  141.             pi->dseg_addr += i;
  142.             if(pass == PASS_1)
  143.                 pi->dseg_count++;
  144.             break;
  145.         case DIRECTIVE_CSEG:
  146.             pi->segment = SEGMENT_CODE;
  147.             break;
  148.         case DIRECTIVE_DB:
  149.             return(parse_db(pi, next, pass));
  150.             break;
  151.         case DIRECTIVE_DEF:
  152.             if(!next)
  153.                 {
  154.                 print_msg(pi, MSGTYPE_ERROR, ".DEF needs an operand");
  155.                 return(True);
  156.                 }
  157.             data = get_next_token(next, TERM_EQUAL);
  158.             if(!(data && (tolower(data[0]) == 'r') && isdigit(data[1])))
  159.                 {
  160.                 print_msg(pi, MSGTYPE_ERROR, "%s needs a register (e.g. .def BZZZT = r16)", next);
  161.                 return(True);
  162.                 }
  163.             i = atoi(&data[1]);
  164.             if(i > 31)
  165.                 print_msg(pi, MSGTYPE_ERROR, "R%d is not a valid register", i);
  166.             for(def = pi->first_def; def; def = def->next)
  167.                 if(!nocase_strcmp(def->name, next))
  168.                     {
  169.                     def->reg = i;
  170.                     return(True);
  171.                     }
  172.             def = malloc(sizeof(struct def));
  173.             if(!def)
  174.                 {
  175.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  176.                 return(False);
  177.                 }
  178.             def->next = NULL;
  179.             if(pi->last_def)
  180.                 pi->last_def->next = def;
  181.             else
  182.                 pi->first_def = def;
  183.             pi->last_def = def;
  184.             def->name = malloc(strlen(next) + 1);
  185.             if(!def->name)
  186.                 {
  187.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  188.                 return(False);
  189.                 }
  190.             strcpy(def->name, next);
  191.             def->reg = i;
  192.             break;
  193.         case DIRECTIVE_DEVICE:
  194.             if(pass == PASS_2)
  195.                 return(True);
  196.             if(!next)
  197.                 {
  198.                 print_msg(pi, MSGTYPE_ERROR, ".DEVICE needs an operand");
  199.                 return(True);
  200.                 }
  201.             get_next_token(next, TERM_END);
  202.             pi->device = get_device(next);
  203.             if(!pi->device)
  204.                 print_msg(pi, MSGTYPE_ERROR, "Unknown device: %s", next);
  205.             break;
  206.         case DIRECTIVE_DSEG:
  207.             pi->segment = SEGMENT_DATA;
  208.             break;
  209.         case DIRECTIVE_DW:
  210.             if(pi->segment == SEGMENT_DATA)
  211.                 {
  212.                 print_msg(pi, MSGTYPE_ERROR, "Can't use .DW directive in data segment (.DSEG)");
  213.                 return(True);
  214.                 }
  215.             while(next)
  216.                 {
  217.                 data = get_next_token(next, TERM_COMMA);
  218.                 if(!get_expr(pi, next, &i))
  219.                     return(False);
  220.                 if((i < -32768) || (i > 65535))
  221.                     print_msg(pi, MSGTYPE_ERROR, "Value %d is out of range (-32768 <= k <= 65535)", i);
  222.                 if(pi->segment == SEGMENT_EEPROM)
  223.                     {
  224.                     if(pass == PASS_2)
  225.                         {
  226.                         write_ee_byte(pi, pi->eseg_addr, (unsigned char)i);
  227.                         write_ee_byte(pi, pi->eseg_addr + 1, (unsigned char)(i >> 8));
  228.                         }
  229.                     pi->eseg_addr += 2;
  230.                     if(pass == PASS_1)
  231.                         pi->eseg_count += 2;
  232.                     }
  233.                 else
  234.                     {
  235.                     if((pass == PASS_2) && pi->hfi)
  236.                         write_prog_word(pi, pi->cseg_addr, i);
  237.                     pi->cseg_addr++;
  238.                     if(pass == PASS_1)
  239.                         pi->cseg_count++;
  240.                     }
  241.                 next = data;
  242.                 }
  243.             break;
  244.         case DIRECTIVE_ENDM:
  245.         case DIRECTIVE_ENDMACRO:
  246.             print_msg(pi, MSGTYPE_ERROR, "No .MACRO found before .ENDMACRO");
  247.             break;
  248.         case DIRECTIVE_EQU:
  249.             if(!next)
  250.                 {
  251.                 print_msg(pi, MSGTYPE_ERROR, ".EQU needs an operand");
  252.                 return(True);
  253.                 }
  254.             data = get_next_token(next, TERM_EQUAL);
  255.             if(!data)
  256.                 {
  257.                 print_msg(pi, MSGTYPE_ERROR, "%s needs an expression (e.g. .EQU BZZZT = 0x2a)", next);
  258.                 return(True);
  259.                 }
  260.             get_next_token(data, TERM_END);
  261.             if(!get_expr(pi, data, &i))
  262.                 return(False);
  263.             for(label = pi->first_label; label; label = label->next)
  264.                 {
  265.                 if(!nocase_strcmp(label->name, next))
  266.                     {
  267.                     print_msg(pi, MSGTYPE_ERROR, "%s have already been defined as a label", next);
  268.                     return(True);
  269.                     }
  270.                 }
  271.             for(label = pi->first_variable; label; label = label->next)
  272.                 if(!nocase_strcmp(label->name, next))
  273.                     {
  274.                     print_msg(pi, MSGTYPE_ERROR, "%s have already been defined as a .SET variable", next);
  275.                     return(True);
  276.                     }
  277.             for(label = pi->first_constant; label; label = label->next)
  278.                 if(!nocase_strcmp(label->name, next))
  279.                     {
  280.                     print_msg(pi, MSGTYPE_ERROR, "Can't redefine constant %s, use .SET instead", next);
  281.                     return(True);
  282.                     }
  283.             label = malloc(sizeof(struct label));
  284.             if(!label)
  285.                 {
  286.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  287.                 return(False);
  288.                 }
  289.             label->next = NULL;
  290.             if(pi->last_constant)
  291.                 pi->last_constant->next = label;
  292.             else
  293.                 pi->first_constant = label;
  294.             pi->last_constant = label;
  295.             label->name = malloc(strlen(next) + 1);
  296.             if(!label->name)
  297.                 {
  298.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  299.                 return(False);
  300.                 }
  301.             strcpy(label->name, next);
  302.             label->value = i;
  303.             break;
  304.         case DIRECTIVE_ESEG:
  305.             pi->segment = SEGMENT_EEPROM;
  306.             break;
  307.         case DIRECTIVE_EXIT:
  308.             pi->fi->exit_file = True;
  309.             break;
  310.         case DIRECTIVE_INCLUDE:
  311.             if(!next)
  312.                 {
  313.                 print_msg(pi, MSGTYPE_ERROR, "Nothing to include");
  314.                 return(True);
  315.                 }
  316.             next = term_string(pi, next);
  317.             if((pass == PASS_2) && pi->list_line && pi->list_on)
  318.                 {
  319.                 fprintf(pi->list_file, "          %s", pi->list_line);
  320.                 pi->list_line = NULL;
  321.                 }
  322.             fi_bak = pi->fi;
  323.             ok = parse_file(pi, next, pass);
  324.             pi->fi = fi_bak;
  325.             break;
  326.         case DIRECTIVE_LIST:
  327.             if(pass == PASS_2)
  328.                 pi->list_on = True;
  329.             break;
  330.         case DIRECTIVE_LISTMAC:
  331.             if(pass == PASS_2)
  332.                 SET_ARG(pi->args, ARG_LISTMAC, True);
  333.             break;
  334.         case DIRECTIVE_MACRO:
  335.             return(read_macro(pi, next, pass));
  336.             break;
  337.         case DIRECTIVE_NOLIST:
  338.             if(pass == PASS_2)
  339.                 pi->list_on = False;
  340.             break;
  341.         case DIRECTIVE_ORG:
  342.             if(!next)
  343.                 {
  344.                 print_msg(pi, MSGTYPE_ERROR, ".ORG needs an operand");
  345.                 return(True);
  346.                 }
  347.             get_next_token(next, TERM_END);
  348.             if(!get_expr(pi, next, &i))
  349.                 return(False);
  350.             switch(pi->segment)
  351.                 {
  352.                 case SEGMENT_CODE:
  353.                     pi->cseg_addr = i;
  354.                     break;
  355.                 case SEGMENT_DATA:
  356.                     pi->dseg_addr = i;
  357.                     break;
  358.                 case SEGMENT_EEPROM:
  359.                     pi->eseg_addr = i;
  360.                 }
  361.             if(pi->fi->label)
  362.                 pi->fi->label->value = i;
  363.             break;
  364.         case DIRECTIVE_SET:
  365.             if(!next)
  366.                 {
  367.                 print_msg(pi, MSGTYPE_ERROR, ".SET needs an operand");
  368.                 return(True);
  369.                 }
  370.             data = get_next_token(next, TERM_EQUAL);
  371.             if(!data)
  372.                 {
  373.                 print_msg(pi, MSGTYPE_ERROR, "%s needs an expression (e.g. .SET BZZZT = 0x2a)", next);
  374.                 return(True);
  375.                 }
  376.             get_next_token(data, TERM_END);
  377.             if(!get_expr(pi, data, &i))
  378.                 return(False);
  379.             for(label = pi->first_label; label; label = label->next)
  380.                 if(!nocase_strcmp(label->name, next))
  381.                     {
  382.                     print_msg(pi, MSGTYPE_ERROR, "%s have already been defined as a label", next);
  383.                     return(True);
  384.                     }
  385.             for(label = pi->first_constant; label; label = label->next)
  386.                 if(!nocase_strcmp(label->name, next))
  387.                     {
  388.                     print_msg(pi, MSGTYPE_ERROR, "%s have already been defined as a .EQU constant", next);
  389.                     return(True);
  390.                     }
  391.             for(label = pi->first_variable; label; label = label->next)
  392.                 if(!nocase_strcmp(label->name, next))
  393.                     {
  394.                     label->value = i;
  395.                     return(True);
  396.                     }
  397.             label = malloc(sizeof(struct label));
  398.             if(!label)
  399.                 {
  400.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  401.                 return(False);
  402.                 }
  403.             label->next = NULL;
  404.             if(pi->last_variable)
  405.                 pi->last_variable->next = label;
  406.             else
  407.                 pi->first_variable = label;
  408.             pi->last_variable = label;
  409.             label->name = malloc(strlen(next) + 1);
  410.             if(!label->name)
  411.                 {
  412.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  413.                 return(False);
  414.                 }
  415.             strcpy(label->name, next);
  416.             label->value = i;
  417.             break;
  418.         case DIRECTIVE_DEFINE:
  419.             if(!next)
  420.                 {
  421.                 print_msg(pi, MSGTYPE_ERROR, ".DEFINE needs an operand");
  422.                 return(True);
  423.                 }
  424.             data = get_next_token(next, TERM_SPACE);
  425.             if(data)
  426.                 {
  427.                 get_next_token(data, TERM_END);
  428.                 if(!get_expr(pi, data, &i))
  429.                         return(False);
  430.                 }
  431.             else
  432.                 i = 1;
  433.             for(label = pi->first_label; label; label = label->next)
  434.                 if(!nocase_strcmp(label->name, next))
  435.                     {
  436.                     print_msg(pi, MSGTYPE_ERROR, "%s have already been defined as a label", next);
  437.                     return(True);
  438.                     }
  439.             for(label = pi->first_variable; label; label = label->next)
  440.                 if(!nocase_strcmp(label->name, next))
  441.                     {
  442.                     print_msg(pi, MSGTYPE_ERROR, "%s have already been defined as a .SET variable", next);
  443.                     return(True);
  444.                     }
  445.             for(label = pi->first_constant; label; label = label->next)
  446.                 if(!nocase_strcmp(label->name, next))
  447.                     {
  448.                     print_msg(pi, MSGTYPE_ERROR, "Can't redefine constant %s, use .SET instead", next);
  449.                     return(True);
  450.                     }
  451.             label = malloc(sizeof(struct label));
  452.             if(!label)
  453.                 {
  454.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  455.                 return(False);
  456.                 }
  457.             label->next = NULL;
  458.             if(pi->last_constant)
  459.                 pi->last_constant->next = label;
  460.             else
  461.                 pi->first_constant = label;
  462.             pi->last_constant = label;
  463.             label->name = malloc(strlen(next) + 1);
  464.             if(!label->name)
  465.                 {
  466.                 print_msg(pi, MSGTYPE_OUT_OF_MEM, NULL);
  467.                 return(False);
  468.                 }
  469.             strcpy(label->name, next);
  470.             label->value = i;
  471.             break;
  472.         case DIRECTIVE_UNDEF: // TODO
  473.             break;
  474.         case DIRECTIVE_IFDEF:
  475.             if(!next)
  476.                 {
  477.                 print_msg(pi, MSGTYPE_ERROR, ".IFDEF needs an operand");
  478.                 return(True);
  479.                 }
  480.             get_next_token(next, TERM_END);
  481.             if(get_symbol(pi, next, NULL))
  482.                 pi->conditional_depth++;
  483.             else
  484.                     {
  485.                 if(!spool_conditional(pi, False))
  486.                         return(False);
  487.                 }
  488.             break;
  489.         case DIRECTIVE_IFNDEF:
  490.             if(!next)
  491.                 {
  492.                 print_msg(pi, MSGTYPE_ERROR, ".IFNDEF needs an operand");
  493.                 return(True);
  494.                 }
  495.             get_next_token(next, TERM_END);
  496.             if(get_symbol(pi, next, NULL))
  497.                     {
  498.                 if(!spool_conditional(pi, False))
  499.                         return(False);
  500.                 }
  501.             else
  502.                 pi->conditional_depth++;
  503.             break;
  504.         case DIRECTIVE_IF:
  505.             if(!next)
  506.                 {
  507.                 print_msg(pi, MSGTYPE_ERROR, ".IF needs an expression");
  508.                 return(True);
  509.                 }
  510.             get_next_token(next, TERM_END);
  511.             if(!get_expr(pi, next, &i))
  512.                     return(False);
  513.             if(i)
  514.                 pi->conditional_depth++;
  515.             else
  516.                     {
  517.                 if(!spool_conditional(pi, False))
  518.                         return(False);
  519.                 }
  520.             break;
  521.         case DIRECTIVE_ELSE:
  522.         case DIRECTIVE_ELIF:
  523.                 if(!spool_conditional(pi, True))
  524.                     return(False);
  525.             break;
  526.         case DIRECTIVE_ENDIF:
  527.                 if(pi->conditional_depth == 0)
  528.                     print_msg(pi, MSGTYPE_ERROR, "Too many .ENDIF");
  529.             else
  530.                     pi->conditional_depth--;
  531.             break;
  532.         case DIRECTIVE_MESSAGE:
  533.             if(pass == PASS_1)
  534.                 return(True);
  535.             if(!next)
  536.                 {
  537.                 print_msg(pi, MSGTYPE_ERROR, "No message string supplied");
  538.                 return(True);
  539.                 }
  540.             next = term_string(pi, next);
  541.             print_msg(pi, MSGTYPE_MESSAGE, next);
  542.             break;
  543.         case DIRECTIVE_WARNING:
  544.             if(pass == PASS_1)
  545.                 return(True);
  546.             if(!next)
  547.                 {
  548.                 print_msg(pi, MSGTYPE_ERROR, "No warning string supplied");
  549.                 return(True);
  550.                 }
  551.             next = term_string(pi, next);
  552.             print_msg(pi, MSGTYPE_WARNING, next);
  553.             break;
  554.         case DIRECTIVE_ERROR:
  555.             if(pass == PASS_1)
  556.                 return(True);
  557.             if(!next)
  558.                 {
  559.                 print_msg(pi, MSGTYPE_ERROR, "No error string supplied");
  560.                 return(True);
  561.                 }
  562.             next = term_string(pi, next);
  563.             print_msg(pi, MSGTYPE_ERROR, next);
  564.             break;
  565.         }
  566.     return(ok);
  567.     }
  568.  
  569.  
  570. int get_directive_type(char *directive)
  571.     {
  572.     int i;
  573.  
  574.     for(i = 0; i < DIRECTIVE_COUNT; i++)
  575.         if(!strcmp(directive, directive_list[i])) return(i);
  576.     return(-1);
  577.     }
  578.  
  579.  
  580. char *term_string(struct prog_info *pi, char *string)
  581.     {
  582.     int i;
  583.  
  584.     if(string[0] != '\"') 
  585.         print_msg(pi, MSGTYPE_ERROR, "String must be enclosed in \"-signs");
  586.     else
  587.         string++;
  588.     for(i = 0; (string[i] != '\"') && !((string[i] == 10) || (string[i] == 13) || (string[i] == '\0')); i++);
  589.     if((string[i] == 10) || (string[i] == 13) || (string[i] == '\0'))
  590.         print_msg(pi, MSGTYPE_ERROR, "String is missing a closing \"-sign");
  591.     string[i] = '\0';
  592.     return(string);
  593.     }
  594.  
  595.  
  596. int parse_db(struct prog_info *pi, char *next, int pass)
  597.     {
  598.     int i, count;
  599.     char *data, prev;
  600.  
  601.     if(pi->segment == SEGMENT_DATA)
  602.         {
  603.         print_msg(pi, MSGTYPE_ERROR, "Can't use .DB directive in data segment (.DSEG)");
  604.         return(True);
  605.         }
  606.     count = 0;
  607.     while(next)
  608.         {
  609.         data = get_next_token(next, TERM_COMMA);
  610.         if(next[0] == '\"')
  611.             {
  612.             next = term_string(pi, next);
  613.             while(*next != '\0')
  614.                 {
  615.                 count++;
  616.                 write_db(pi, *next, &prev, count, pass);
  617.                 next++;
  618.                 }
  619.             }
  620.         else
  621.             {
  622.             if(!get_expr(pi, next, &i))
  623.                 return(False);
  624.             if((i < -128) || (i > 255))
  625.                 print_msg(pi, MSGTYPE_ERROR, "Value %d is out of range (-128 <= k <= 255)", i);
  626.             count++;
  627.             write_db(pi, (char)i, &prev, count, pass);
  628.             }
  629.         next = data;
  630.         }
  631.     if(pi->segment == SEGMENT_CODE)
  632.         {
  633.         if((count % 2) == 1)
  634.             {
  635.             if(pass == PASS_2)
  636.                 write_prog_word(pi, pi->cseg_addr, prev & 0xff);
  637.             pi->cseg_addr++;
  638.             if(pass == PASS_1)
  639.                 pi->cseg_count++;
  640.             }
  641.         }
  642.     return(True);
  643.     }
  644.  
  645.  
  646. void write_db(struct prog_info *pi, char byte, char *prev, int count, int pass)
  647.     {
  648.     if(pi->segment == SEGMENT_EEPROM)
  649.         {
  650.         if(pass == PASS_2)
  651.             write_ee_byte(pi, pi->eseg_addr, byte);
  652.         pi->eseg_addr++;
  653.         if(pass == PASS_1)
  654.             pi->eseg_count++;
  655.         }
  656.     else /* pi->segment == SEGMENT_CODE */
  657.         {
  658.         if((count % 2) == 0)
  659.             {
  660.             if(pass == PASS_2)
  661.                 write_prog_word(pi, pi->cseg_addr, (byte << 8) | (*prev & 0xff));
  662.             pi->cseg_addr++;
  663.             if(pass == PASS_1)
  664.                 pi->cseg_count++;
  665.             }
  666.         else
  667.             *prev = byte;
  668.         }
  669.     }
  670.  
  671.  
  672. int spool_conditional(struct prog_info *pi, int only_endif)
  673.     {
  674.     int current_depth = 0, do_next;
  675.  
  676.     if(pi->macro_line)
  677.         {
  678.         while((pi->macro_line = pi->macro_line->next))
  679.             {
  680.             pi->macro_call->line_index++;
  681.             if(check_conditional(pi, pi->macro_line->line, ¤t_depth,  &do_next, only_endif))
  682.                 {
  683.                 if(!do_next)
  684.                     return(True);
  685.                 }
  686.             else
  687.                 return(False);
  688.             }
  689.         print_msg(pi, MSGTYPE_ERROR, "Found no closing .ENDIF in macro");
  690.         }
  691.     else
  692.         {
  693.         while(fgets(pi->fi->buff, LINEBUFFER_LENGTH, pi->fi->fp))
  694.             {
  695.             pi->fi->line_number++;
  696.             if(check_conditional(pi, pi->fi->buff, ¤t_depth,  &do_next, only_endif))
  697.                 {
  698.                 if(!do_next)
  699.                     return(True);
  700.                 }
  701.             else
  702.                 return(False);
  703.             }
  704.         if(feof(pi->fi->fp))
  705.             {
  706.             print_msg(pi, MSGTYPE_ERROR, "Found no closing .ENDIF");
  707.             return(True);
  708.             }
  709.         else
  710.             {
  711.             perror(pi->fi->include_file->name);
  712.             return(False);
  713.             }
  714.         }
  715.     return(True);
  716.     }
  717.  
  718.  
  719. int check_conditional(struct prog_info *pi, char *buff, int *current_depth, int *do_next, int only_endif)
  720.     {
  721.     int i = 0;
  722.     char *next;
  723.  
  724.     *do_next = False;
  725.     while(IS_HOR_SPACE(buff[i]) && !IS_END(buff[i])) i++;
  726.     if(buff[i] == '.')
  727.         {
  728.         i++;
  729.         if(!nocase_strncmp(&buff[i], "if", 2))
  730.             (*current_depth)++;
  731.         else if(!nocase_strncmp(&buff[i], "endif", 5))
  732.                 {
  733.             if(*current_depth == 0)
  734.                     return(True);
  735.             (*current_depth)--;
  736.             }
  737.         else if(!only_endif && (*current_depth == 0))
  738.                 {
  739.             if(!nocase_strncmp(&buff[i], "else", 4))
  740.                     {
  741.                 pi->conditional_depth++;
  742.                     return(True);
  743.                 }
  744.             else if(!nocase_strncmp(&buff[i], "elif", 4))
  745.                     {
  746.                 next = get_next_token(&buff[i], TERM_SPACE);
  747.                 if(!next)
  748.                         {
  749.                     print_msg(pi, MSGTYPE_ERROR, ".ELIF needs an operand");
  750.                     return(True);
  751.                     }
  752.                 get_next_token(next, TERM_END);
  753.                 if(!get_expr(pi, next, &i))
  754.                         return(False);
  755.                 if(i)
  756.                         pi->conditional_depth++;
  757.                 else
  758.                         {
  759.                         if(!spool_conditional(pi, False))
  760.                             return(False);
  761.                     }
  762.                 return(True);
  763.                 }
  764.             }
  765.         }
  766.     *do_next = True;
  767.     return(True);
  768.     }
  769.